package com.bicntech.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bicntech.common.constant.UserConstants;
import com.bicntech.common.core.domain.TreeEntity;
import com.bicntech.common.exception.ServiceException;
import com.bicntech.common.utils.ObjectUtil;
import com.bicntech.common.utils.TreeBuildUtils;
import com.bicntech.system.dto.UserDeptUpdateDTO;
import com.bicntech.system.dto.WechatUserDeptRequestDTO;
import com.bicntech.system.entity.UserInfo;
import com.bicntech.system.entity.WechatUserDept;
import com.bicntech.system.mapper.WechatUserDeptMapper;
import com.bicntech.system.service.UserInfoService;
import com.bicntech.system.service.WechatUserDeptService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;

/**
 * <p>
 *
 * @author bicntech
 * @description:微信用户组织管理 服务实现类
 * </p>
 * @date 2023-08-16
 */
@Slf4j
@Service
public class WechatUserDeptServiceImpl extends ServiceImpl<WechatUserDeptMapper, WechatUserDept> implements WechatUserDeptService {

    @Resource
    private WechatUserDeptMapper baseMapper;

    @Resource
    private UserInfoService userInfoService;


    @Override
    public List<WechatUserDept> selectDeptList() {
        return super.lambdaQuery()
                .orderByAsc(WechatUserDept::getParentId)
                .orderByAsc(WechatUserDept::getOrderNum)
                .list();
    }

    @Override
    public List<Tree<Long>> buildDeptTreeSelect(List<WechatUserDept> depts) {
        if (CollUtil.isEmpty(depts)) {
            return CollUtil.newArrayList();
        }
        return TreeBuildUtils.build(depts, (dept, tree) ->
                tree.setId(dept.getDeptId())
                        .setParentId(dept.getParentId())
                        .setName(dept.getDeptName())
                        .setWeight(dept.getOrderNum()));
    }

    @Override
    public String checkDeptNameUnique(WechatUserDeptRequestDTO dept) {
        boolean exist = baseMapper.exists(new LambdaQueryWrapper<WechatUserDept>()
                .eq(WechatUserDept::getDeptName, dept.getDeptName())
                .eq(WechatUserDept::getParentId, ObjectUtil.notEmpty(dept.getParentId()) ? dept.getParentId() : 0L)
                .ne(ObjectUtil.notEmpty(dept.getDeptId()), WechatUserDept::getDeptId, dept.getDeptId()));
        if (exist) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public Long insertDept(WechatUserDeptRequestDTO dept) {
//        WechatUserDept info = super.getById(dept.getParentId());
//        if (!ObjectUtil.notEmpty(info)) {
//            throw new ServiceException("父部门不存在");
//        }
        WechatUserDept wechatUserDept = ObjectUtil.entityToModel(dept, WechatUserDept.class);
        if (super.save(wechatUserDept)) {
            log.info("插入WechatUserDept成功,id为{}", wechatUserDept.getDeptId());
            return wechatUserDept.getDeptId();
        } else {
            throw new ServiceException("添加失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long updateDept(WechatUserDeptRequestDTO dept) {
        WechatUserDept deptInfo = super.getById(dept.getDeptId());
        WechatUserDept wechatUserDept = ObjectUtil.entityToModel(dept, WechatUserDept.class);
        if (super.updateById(wechatUserDept)) {
            if (!StrUtil.equals(deptInfo.getDeptName(), dept.getDeptName())) {
                userInfoService.lambdaUpdate()
                        .set(UserInfo::getDepartmentName, dept.getDeptName())
                        .eq(UserInfo::getDepartmentId, dept.getDeptId())
                        .update();
            }
            return wechatUserDept.getDeptId();
        } else {
            throw new ServiceException("更新失败[id=" + wechatUserDept.getDeptId() + "]");
        }
    }

    @Override
    public boolean hasChildByDeptId(Long deptId) {
        return baseMapper.exists(new LambdaQueryWrapper<WechatUserDept>()
                .eq(WechatUserDept::getParentId, deptId));
    }

    @Override
    public Long deleteDeptById(Long deptId) {
        if (super.removeById(deptId)) {
            return deptId;
        } else {
            throw new ServiceException("删除失败[id=" + deptId + "]");
        }
    }

    @Override
    public boolean checkDeptExistUser(Long deptId) {
        return userInfoService
                .lambdaQuery()
                .eq(UserInfo::getDepartmentId, deptId)
                .exists();
    }

    @Override
    public void editUser(UserDeptUpdateDTO userDeptUpdateDTO) {
        WechatUserDept wechatUserDept = Optional.ofNullable(super.getById(userDeptUpdateDTO.getDeptId()))
                .filter(ObjectUtil::notEmpty)
                .orElseThrow(() -> new ServiceException("部门不存在！"));
        Optional.ofNullable(userInfoService.getById(userDeptUpdateDTO.getUserId()))
                .filter(ObjectUtil::notEmpty)
                .orElseThrow(() -> new ServiceException("用户不存在！"));
        userInfoService.lambdaUpdate()
                .set(UserInfo::getDepartmentName, wechatUserDept.getDeptName())
                .set(UserInfo::getDepartmentId, userDeptUpdateDTO.getDeptId())
                .eq(UserInfo::getId, userDeptUpdateDTO.getUserId())
                .update();
    }

    @Override
    public IPage<WechatUserDept> pageSelect(String deptName, Long deptId, IPage<WechatUserDept> packPage) {
        return super.lambdaQuery()
                .like(StrUtil.isNotBlank(deptName), WechatUserDept::getDeptName, deptName)
                .eq(ObjectUtil.notEmpty(deptId), TreeEntity::getParentId, deptId)
                .orderByAsc(WechatUserDept::getParentId)
                .orderByAsc(WechatUserDept::getOrderNum)
                .page(packPage);
    }

    @Override
    public WechatUserDept selectDeptById(Long deptId) {
        return baseMapper.selectById(deptId);
    }

}
